import 'package:flutter/material.dart';

typedef AnimationWidgetWrapBuilder = Widget Function(
    Widget? child, double value);

class AnimationWidgetController {
  AnimationController? _controller;
  final double? value;
  final double begin;
  final double end;
  final bool reverse;
  final bool autoPlay;
  final Duration duration;
  final Duration? reverseDuration;

  AnimationWidgetController({
    this.value,
    required this.begin,
    required this.end,
    required this.duration,
    this.reverse = true,
    this.autoPlay = false,
    this.reverseDuration,
  });
  bool get isAnimating => _controller?.isAnimating ?? false;

  start() {
    _controller?.repeat(reverse: reverse);
  }

  stop({bool canceled = true}) async {
    _controller?.stop(canceled: canceled);
  }
}

class AnimatedWidgetWrap extends StatefulWidget {
  final AnimationWidgetController controller;
  final Widget? child;
  final AnimationWidgetWrapBuilder builder;

  const AnimatedWidgetWrap({
    Key? key,
    required this.controller,
    required this.builder,
    this.child,
  }) : super(key: key);

  @override
  State<AnimatedWidgetWrap> createState() => _AnimatedWidgetWrapState();
}

class _AnimatedWidgetWrapState extends State<AnimatedWidgetWrap>
    with SingleTickerProviderStateMixin {
  Animation<double>? _animation;
  AnimationController? _animateController;

  @override
  void initState() {
    _animateController = AnimationController(
      value: widget.controller.value,
      duration: widget.controller.duration,
      reverseDuration: widget.controller.reverseDuration,
      vsync: this,
    );
    _animateController?.addStatusListener(listener);
    _animation = Tween(
      begin: widget.controller.begin,
      end: widget.controller.end,
    ).animate(_animateController!);
    widget.controller._controller = _animateController;
    if (widget.controller.autoPlay) {
      widget.controller.start();
    }
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _animation!,
      child: widget.child,
      builder: (BuildContext ctx, Widget? child) {
        return widget.builder.call(child, _animation!.value);
      },
    );
  }

  listener(AnimationStatus status) {
    // tdLog('AnimationStatus------$status');
  }

  @override
  void dispose() {
    _animateController?.removeStatusListener(listener);
    _animateController?.dispose();
    _animateController = null;
    super.dispose();
  }
}
